package o.json;

import java.io.IOException;
import java.io.StringWriter;
import java.io.Writer;
import java.util.Collection;

public class JSONWriter {
//	protected final StringBuffer buffer = new StringBuffer();

	protected final Writer writer;
	public JSONWriter() {
		this.writer = new StringWriter();
	}
	public JSONWriter(Writer writer) {
		this.writer = writer;
	}

	public void writeObject(JSONObject object) throws IOException {
//		buffer.append("{");
		writer.append("{");

		int i = 0;
		final Collection<JSONString> keys = object.getKeys();
		for (JSONString key : keys) {
			final JSONValue value = object.getValue(key);

			write(key);
//			buffer.append(":");
			writer.append(":");
			write(value);

//			if (++i < keys.size()) buffer.append(",");
			if (++i < keys.size()) writer.append(",");
		}

//		buffer.append("}");
		writer.append("}");
	}

	public void writeArray(JSONArray array) throws IOException {
//		buffer.append("[");
		writer.append("[");

		int i = 0;
		for (JSONValue value : array) {
			write(value);

//			if (++i < array.getLength()) buffer.append(",");
			if (++i < array.getLength()) writer.append(",");
		}

//		buffer.append("]");
		writer.append("]");
	}

	public void write(JSONValue value) {
		try {
			if (value.isString()) {
				writeString(value.getString());
				return;
			}
			if (value.isNumber()) {
				writeNumber(value.getNumber());
				return;
			}
			if (value.isObject()) {
				writeObject(value.getObject());
				return;
			}
			if (value.isArray()) {
				writeArray(value.getArray());
				return;
			}
			if (value.isTrue()) {
				writeTrue(value.getTrue());
				return;
			}
			if (value.isFalse()) {
				writeFalse(value.getFalse());
				return;
			}
			if (value.isNull()) {
				writeNull(value.getNull());
				return;
			}

			throw new JSONException("value is not recognized!");
		} catch (JSONException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public void writeString(JSONString string) throws IOException {
//		buffer.append("\"");
		writer.append("\"");

//		buffer.append(string.getValue());
		writer.append(string.getValue());

//		buffer.append("\"");
		writer.append("\"");
	}

	public void writeNumber(JSONNumber number) throws IOException {
//		buffer.append(number.getValue());
		writer.append(String.valueOf(number.getValue()));
	}

	public void writeTrue(JSONTrue t) throws IOException {
//		buffer.append("true");
		writer.append("true");
	}

	public void writeFalse(JSONFalse f) throws IOException {
//		buffer.append("false");
		writer.append("false");
	}

	public void writeNull(JSONNull n) throws IOException {
//		buffer.append("null");
		writer.append("null");
	}

	@Override
	public String toString() {
//		return buffer.toString();
		if (writer instanceof StringWriter) {
			final StringWriter sw = (StringWriter) writer;
			return sw.getBuffer().toString();
		}
		return "[JSONWriter]";
	}
}
